<?php


namespace app\game\services;


use app\common\models\User;
use app\common\models\UserWallet;
use app\common\models\UserWalletLog;
use app\Request;
use app\xiangji\exception\BadRequestException;
use app\xiangji\exception\InvalidArgumentException;
use app\xiangji\exception\ModelNotFoundException;
use app\xiangji\exception\ServiceUnavailableException;
use think\Exception;
use think\facade\Db;

class GameService
{
    private $userWalletModel;
    private $userWalletLogModel;

    public function __construct(UserWallet $userWalletModel, UserWalletLog $userWalletLogModel)
    {
        $this->userWalletModel      = $userWalletModel;
        $this->userWalletLogModel   = $userWalletLogModel;
    }

    /**
     * [
     *  'app_id' => '******',
     *  'app_secret => '*****',
     *  'data' => [
     *          ['union_id' => 'xxxxxxxxx', 'amount' => 222],
     *          ['union_id' => 'xxxxxxxxx', 'amount' => 222],
     *      ]
     * ]
     * @param Request $request
     * @return bool
     * @throws Exception
     * @throws ModelNotFoundException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function syncInsertLogData(Request $request)
    {
        $data = $request->post('data', []);
        // 限制每次同步的数量
        if (count($data) > 1000){
            throw new BadRequestException('同步数据过多，每次同步最多1000条');
        }
        // 查询用户和用户的钱包数据
        $users = User::whereIn('unionId', array_unique(array_column($data, 'union_id')))->with(['wallet'])->select();
        if ($users->isEmpty()){
            throw new ModelNotFoundException("该用户未注册，请先注册");
        }

        // 组合数据，用于批量更新数据
        $wallet_logs = [];  // 日志信息新增数组
        $wallets = [];      // 钱包更新数组
        foreach ($users as $user){
            foreach ($data as $item){
                if (!is_numeric($item['amount'])){
                    throw new InvalidArgumentException('金额格式错误：应为非负整数');
                }
                if ($item['union_id'] != $user->unionId) continue;
                // 钱包日志
                $wallet_logs[] = [
                    'wallet_id'     => $user->wallet->id,
                    'user_id'       => $user->id,
                    'change'        => $item['amount'],
                    'scene'         => $request->game_name,
                    'amount_before' => $user->wallet->balance,
                    'amount_after'  => $user->wallet->balance + $item['amount']
                ];
                // 更新该用户的钱包余额
                $user->wallet->balance = $user->wallet->balance + $item['amount'];
                $user->wallet->income = $user->wallet->income + $item['amount'];
            }
            // 钱包账户
            $wallets[] = [
                'id'        => $user->wallet->id,
                'balance'   => $user->wallet->balance,
                'income'    => $user->wallet->income
            ];
        }
        // 更新数据库
        Db::startTrans();
        try {
            $this->userWalletLogModel->saveAll($wallet_logs);
            $this->userWalletModel->saveAll($wallets);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            throw new ServiceUnavailableException('同步失败：'.$e->getMessage(), $e->getCode());
        }
        return 'ok';
    }
}
